package com.screen.screendisplay.service.impl.electric;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.screen.screendisplay.entity.electric.ElectricSafetyenvPlantRt;
import com.screen.screendisplay.mapper.electric.ElectricSafetyenvPlantRtMapper;
import com.screen.screendisplay.service.electric.ElectricSafetyenvPlantRtService;
import com.screen.screendisplay.vo.electric.PlantAnnualEmissionStatistics;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 火电安全环保电厂实时数据表 服务实现类
 * </p>
 *
 * @author xuesong
 * @since 2025-09-24
 */
@Service
public class ElectricSafetyenvPlantRtServiceImpl extends ServiceImpl<ElectricSafetyenvPlantRtMapper, ElectricSafetyenvPlantRt> implements ElectricSafetyenvPlantRtService {

    @Override
    public List<ElectricSafetyenvPlantRt> getByYear(Integer year) {
        return baseMapper.selectByYear(year);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getByYearAndMonth(Integer year, Integer month) {
        return baseMapper.selectByYearAndMonth(year, month);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getByDate(Integer year, Integer month, Integer day) {
        return baseMapper.selectByDate(year, month, day);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getByPlantCode(String plantCode) {
        return baseMapper.selectByPlantCode(plantCode);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getByCompanyCode(String companyCode) {
        return baseMapper.selectByCompanyCode(companyCode);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getExcessiveEmission(Integer year, Integer month) {
        return baseMapper.selectExcessiveEmission(year, month);
    }

    @Override
    public ElectricSafetyenvPlantRt getMonthlyStatistics(Integer year, Integer month, String plantCode) {
        return baseMapper.selectMonthlyStatistics(year, month, plantCode);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getDailyTrend(Integer year, Integer month, String plantCode) {
        return baseMapper.selectDailyTrend(year, month, plantCode);
    }

    @Override
    public boolean hasExcessiveEmission(Integer year, Integer month) {
        List<ElectricSafetyenvPlantRt> excessiveList = getExcessiveEmission(year, month);
        return excessiveList != null && !excessiveList.isEmpty();
    }

    @Override
    public Double getComplianceRate(Integer year, Integer month, String plantCode) {
        // 查询该电厂当月所有数据
        QueryWrapper<ElectricSafetyenvPlantRt> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("year", year)
                   .eq("month", month)
                   .eq("plant_code", plantCode);
        
        List<ElectricSafetyenvPlantRt> allData = list(queryWrapper);
        
        if (allData == null || allData.isEmpty()) {
            return 100.0; // 无数据时返回100%
        }
        
        // 统计达标的数据条数
        long compliantCount = allData.stream()
            .filter(data -> isCompliant(data))
            .count();
        
        // 计算达标率
        double rate = (double) compliantCount / allData.size() * 100;
        return BigDecimal.valueOf(rate)
                .setScale(2, RoundingMode.HALF_UP)
                .doubleValue();
    }

    @Override
    public ElectricSafetyenvPlantRt getLatestDataByPlant(String plantCode) {
        QueryWrapper<ElectricSafetyenvPlantRt> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("plant_code", plantCode)
                   .orderByDesc("year", "month", "day", "create_time")
                   .last("LIMIT 1");
        
        return getOne(queryWrapper);
    }

    @Override
    public List<ElectricSafetyenvPlantRt> getLatestDataByCompany(String companyCode) {
        // 查询该公司下所有电厂的最新数据
        QueryWrapper<ElectricSafetyenvPlantRt> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_code", companyCode);
        
        List<ElectricSafetyenvPlantRt> allData = list(queryWrapper);
        
        if (allData == null || allData.isEmpty()) {
            return allData;
        }
        
        // 按电厂分组，取每个电厂的最新数据
        Map<String, ElectricSafetyenvPlantRt> latestDataMap = allData.stream()
            .collect(Collectors.groupingBy(
                ElectricSafetyenvPlantRt::getPlantCode,
                Collectors.maxBy((a, b) -> {
                    // 按年、月、日、创建时间排序
                    int yearCompare = Integer.compare(a.getYear(), b.getYear());
                    if (yearCompare != 0) return yearCompare;
                    
                    int monthCompare = Integer.compare(a.getMonth(), b.getMonth());
                    if (monthCompare != 0) return monthCompare;
                    
                    int dayCompare = Integer.compare(a.getDay(), b.getDay());
                    if (dayCompare != 0) return dayCompare;
                    
                    if (a.getCreateTime() != null && b.getCreateTime() != null) {
                        return a.getCreateTime().compareTo(b.getCreateTime());
                    }
                    
                    return 0;
                })
            ))
            .entrySet()
            .stream()
            .filter(entry -> entry.getValue().isPresent())
            .collect(Collectors.toMap(
                Map.Entry::getKey,
                entry -> entry.getValue().get()
            ));
        
        return latestDataMap.values().stream().collect(Collectors.toList());
    }

    /**
     * 判断排放数据是否达标
     * @param data 排放数据
     * @return 是否达标
     */
    private boolean isCompliant(ElectricSafetyenvPlantRt data) {
        // 检查粉尘排放是否达标
        if (data.getDustAmount() != null && data.getDustStandard() != null) {
            if (data.getDustAmount() > data.getDustStandard()) {
                return false;
            }
        }
        
        // 检查硫化物排放是否达标
        if (data.getSulfurAmount() != null && data.getSulfurStandard() != null) {
            if (data.getSulfurAmount() > data.getSulfurStandard()) {
                return false;
            }
        }
        
        // 检查氮氧化物排放是否达标
        if (data.getNitrogenAmount() != null && data.getNitrogenStandard() != null) {
            if (data.getNitrogenAmount() > data.getNitrogenStandard()) {
                return false;
            }
        }
        
        return true;
    }

    @Override
    public List<PlantAnnualEmissionStatistics> getPlantAnnualEmissionStatistics(Integer year) {
        List<Map<String, Object>> statisticsMapList = baseMapper.selectPlantAnnualEmissionStatistics(year);
        
        return statisticsMapList.stream()
            .map(this::mapToPlantAnnualEmissionStatistics)
            .collect(Collectors.toList());
    }

    /**
     * 将 Map 转换为 PlantAnnualEmissionStatistics 对象
     * @param map 数据库查询结果 Map
     * @return PlantAnnualEmissionStatistics 对象
     */
    private PlantAnnualEmissionStatistics mapToPlantAnnualEmissionStatistics(Map<String, Object> map) {
        PlantAnnualEmissionStatistics statistics = new PlantAnnualEmissionStatistics();
        
        statistics.setYear(getIntegerValue(map, "year"));
        statistics.setCompanyCode(getStringValue(map, "company_code"));
        statistics.setCompanyName(getStringValue(map, "company_name"));
        statistics.setPlantCode(getStringValue(map, "plant_code"));
        statistics.setPlantName(getStringValue(map, "plant_name"));
        statistics.setUnitCount(getIntegerValue(map, "unit_count"));
        statistics.setStatus(getIntegerValue(map, "status"));
        
        statistics.setTotalDustAmount(getLongValue(map, "total_dust_amount"));
        statistics.setDustStandard(getIntegerValue(map, "dust_standard"));
        statistics.setTotalSulfurAmount(getLongValue(map, "total_sulfur_amount"));
        statistics.setSulfurStandard(getIntegerValue(map, "sulfur_standard"));
        statistics.setTotalNitrogenAmount(getLongValue(map, "total_nitrogen_amount"));
        statistics.setNitrogenStandard(getIntegerValue(map, "nitrogen_standard"));
        
        statistics.setDustComplianceRate(getDoubleValue(map, "dust_compliance_rate"));
        statistics.setSulfurComplianceRate(getDoubleValue(map, "sulfur_compliance_rate"));
        statistics.setNitrogenComplianceRate(getDoubleValue(map, "nitrogen_compliance_rate"));
        statistics.setOverallComplianceRate(getDoubleValue(map, "overall_compliance_rate"));
        statistics.setRecordCount(getIntegerValue(map, "record_count"));
        
        return statistics;
    }

    /**
     * 从 Map 中安全获取 String 值
     */
    private String getStringValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value != null ? value.toString() : null;
    }

    /**
     * 从 Map 中安全获取 Integer 值
     */
    private Integer getIntegerValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).intValue();
        }
        try {
            return Integer.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 从 Map 中安全获取 Long 值
     */
    private Long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        try {
            return Long.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }

    /**
     * 从 Map 中安全获取 Double 值
     */
    private Double getDoubleValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) {
            return null;
        }
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return null;
        }
    }
}
